﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using HCM_maps_website.Process.BLL;
using HCM_maps_website.Models;

namespace HCM_maps_website.Controllers
{
    public class MobileController : Controller
    {
        //
        // GET: /Mobile/
        int[] nPics = new int[] { 6, 4, 12, 9, 28, 19, 57, 39, 97, 75 };
        int[] sizeMaps = new int[] { 1536, 1024, 3072, 2304, 7168, 4864, 14592, 9984, 24832, 19200 };
        float[] rate = new float[] { 1, 1, 2, 2.25f, 4.667f, 4.75f, 9.5f, 9.75f, 16.1666666667f, 18.75f };
        float[] mapCoor = new float[] { 10.897031f, 106.578541f, 10.894079f, 106.58591f, 10.894965f, 106.587296f, 10.890814f, 106.586112f };
        float[] deltaCoor = new float[] { 0.0493095f, 0.0474955f, 0.02437575f, 0.02413f, 0.01220925f, 0.01194825f, 0.00613225f, 0.006016f };
        int[] centerXY = new int[] { 568, 670, 1083, 1282, 2139, 2585, 4331, 4994, 8712, 9948 };
        //float centerLat = 10.773615f; float centerLong = 106.689385f;
        float centerLat = 10.773635f; float centerLong = 106.689385f;
        //float tempLat = 10.776685f; float tempLong = 106.683699f;
        //float distanceLat = 0.00307f; float distanceLong = 0.005689f;
        float distanceLat = 0.00307f; float distanceLong = 0.005686f;
        int pwidth = 256; int pheight = 256;

        ServiceBLL serviceBL = new ServiceBLL();

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult FindDuong(float sLat, float sLong, float eLat, float eLong)
        {


            List<DirectionDTO> listpath = DirectionService.ShortestPaths(new Coordinate(sLat, sLong), new Coordinate(eLat, eLong));

            //List<GraphNodeInfoEx> lstdir = DirectionService.ShortestPath(new Coordinate(sLat, sLong), new Coordinate(eLat, eLong));

            /*List<List<double>> arrListP = new List<List<double>>();

            

            if (listpath != null)
            {
                foreach (DirectionDTO graph in listpath)
                {
                    List<double> arrPoints = new List<double>();

                    foreach (DirectionNode node in graph.Path)
                    {

                        arrPoints.Add(node.Location.Longitude);
                        arrPoints.Add(node.Location.Latitude);
                    }

                    arrListP.Add(arrPoints);
                }
            }*/

            //if (lstdir != null)
            //{
            //    foreach (GraphNodeInfoEx graph in lstdir)
            //    {
            //        arrPoints.Add(graph.Location.Longitude);
            //        arrPoints.Add(graph.Location.Latitude);
            //    }

            //}


            List<List<StreetDir>> arrListP = new List<List<StreetDir>>();



            if (listpath != null)
            {
                foreach (DirectionDTO graph in listpath)
                {
                    List<StreetDir> arrPoints = new List<StreetDir>();

                    foreach (DirectionNode node in graph.Path)
                    {
                        StreetDir strd = new StreetDir()
                        {
                            Mlat = node.Location.Latitude,
                            Mlong = node.Location.Longitude,
                            NextStreet = node.NextStreet,
                            Direction = node.DirectionGuide
                        };
                        arrPoints.Add(strd);
                    }

                    arrListP.Add(arrPoints);
                }
            }

            return Json(arrListP);
        }

        public PartialViewResult Search(string keywords)
        {

            List<int> arrpos = new List<int>();

            for (int i = 1; i < keywords.Length - 1; i++)
            {
                if (keywords[i] == '.' && (keywords[i - 1].ToString().ToLower() == "q" ||
                    (keywords[i - 1].ToString().ToLower() == "p" && (i < 2 || (i >= 2 && keywords[i - 2].ToString().ToLower() != "t")))))
                {
                    arrpos.Add(i);
                }
            }

            for (int i = arrpos.Count - 1; i >= 0; i--)
            {
                keywords = keywords.Remove(arrpos[i], 1);
            }

            SearchResult lstresult = SearchBLL.Search(keywords);

            return PartialView("_InfoMobile", new Tuple<IEnumerable<ServiceModel>, IEnumerable<PlaceModels>>(lstresult.Service, lstresult.Place));
        }


        [HttpPost]
        public ActionResult GetPlaceAroundLongLat(float plat, float plong, int type, int r)
        {
            Coordinate coor = new Coordinate(plat, plong);

            ServiceModel service = SearchBLL.GetNearPlaceCoordinate(coor);

            return PartialView("_InfoMobile", GetPlaceAround(service.Coordinate, type, r));
        }

        private Tuple<IEnumerable<ServiceModel>, IEnumerable<PlaceModels>> GetPlaceAround(Coordinate coor, int type, int r)
        {
            IEnumerable<ServiceModel> services = null;
            if (type == -1)
            {
                services = serviceBL.FindServiceAround(coor, r);
            }
            else
            {
                services = serviceBL.FindServiceAroundWithServiceType(type, coor, r);
            }

            return new Tuple<IEnumerable<ServiceModel>, IEnumerable<PlaceModels>>(services, null);
        }

        [HttpPost]
        public ActionResult GetExactCoordinate(int zoom, int x, int y)
        {
            int deltax = x - centerXY[(zoom - 1) * 2];
            int deltay = y - centerXY[(zoom - 1) * 2 + 1];

            float plat = deltay * distanceLat / (float)(18 * Math.Pow(2, zoom - 1));
            float plong = deltax * distanceLong / (float)(30 * Math.Pow(2, zoom - 1));
            plat += plat * 0.105f;

            float explat = centerLat - plat;
            float explong = centerLong + plong;

            Coordinate coor = new Coordinate(explat, explong);

            ServiceModel place = SearchBLL.GetNearPlaceCoordinate(coor);

            //return Json(new object[] { coor.Longitude, coor.Latitude, place.Area }, JsonRequestBehavior.AllowGet);
            if (place != null)
                return Json(new object[] { place.Coordinate.Longitude, place.Coordinate.Latitude, place.Address, place.FullName }, JsonRequestBehavior.AllowGet);
            else return Json(null, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult GetPlaceAroundPoint(int zoom, int x, int y, int type, int r)
        {
            int deltax = x - centerXY[(zoom - 1) * 2];
            int deltay = y - centerXY[(zoom - 1) * 2 + 1];

            float plat = deltay * distanceLat / (float)(18 * Math.Pow(2, zoom - 1));
            float plong = deltax * distanceLong / (float)(30 * Math.Pow(2, zoom - 1));
            plat += plat * 0.105f;

            float explat = centerLat - plat;
            float explong = centerLong + plong;

            Coordinate coor = new Coordinate(explat, explong);

            ServiceModel service = SearchBLL.GetNearPlaceCoordinate(coor);

            if (service == null) return Json(null);

            Tuple<IEnumerable<ServiceModel>, IEnumerable<PlaceModels>> Model = GetPlaceAround(service.Coordinate, type, r);

            List<List<StreetDir>> arrListP = null;



            if (Model != null && (Model.Item1 !=null || Model.Item2!=null))
            {
                arrListP = new List<List<StreetDir>>();
                List<StreetDir> arrPoints = new List<StreetDir>();
                arrPoints.Add(new StreetDir() { Mlat = service.Coordinate.Latitude, Mlong = service.Coordinate.Longitude });
                if (Model.Item1 != null)
                {
                    foreach (ServiceModel serv in Model.Item1)
                    {
                        StreetDir strd = new StreetDir()
                        {
                            Mlat = serv.Coordinate.Latitude,
                            Mlong = serv.Coordinate.Longitude,
                        };
                        arrPoints.Add(strd);
                    }
                }
                if (Model.Item2 != null)
                {
                    foreach (PlaceModels pl in Model.Item2)
                    {
                        StreetDir strd = new StreetDir()
                        {
                            Mlat = pl.Coordinate.Latitude,
                            Mlong = pl.Coordinate.Longitude,
                        };
                        arrPoints.Add(strd);
                    }
                }
                arrListP.Add(arrPoints);
            }

            return Json(arrListP);
        }


        private string getViewContent(Tuple<IEnumerable<ServiceModel>, IEnumerable<PlaceModels>> Model)
        {
            string str = "";
            if (Model == null || (Model.Item1 == null && Model.Item2 == null)
        || (Model.Item1 == null && Model.Item2.Count() == 0) || (Model.Item2 == null && Model.Item1.Count() == 0)
        || (Model.Item1.Count() == 0 && Model.Item2.Count() == 0))
            {
                str += "<li id='notfound'>Không tìm thấy kết quả</li>";
            }
            else
            {
                if (Model.Item1 != null)
                {
                    foreach (HCM_maps_website.Models.ServiceModel service in Model.Item1)
                    {
                        str += "<li>"
                            + "<h5>" + service.FullName + "</h5>"
                            + "<a class='address'>" + service.Address + "</a>"
                            + "<span class='function' datalat='" + service.Coordinate.Longitude + "' datalong='" + service.Coordinate.Latitude + "'>"
                                + "<a href='javascript:void(0)' class='viewmap'>Xem</a>"
                                + "<a href='javascript:void(0)' class='setstartpoint'>Điểm đi</a>"
                                + "<a href='javascript:void(0)' class='setendpoint'>Điểm đến</a>"
                                + "<a href='javascript:void(0)' class='findplacearound'>Xung quanh</a>"
                            + "</span>"
                        + "</li>";
                    }
                }
                if (Model.Item2 != null)
                {
                    foreach (HCM_maps_website.Models.PlaceModels place in Model.Item2)
                    {
                        str += "<li>"
                            + "<h5>" + place.Name + "</h5>"
                            + "<a class='address'>" + place.HomeNumber + " " + place.Area + "</a>"
                            + "<span class='function' datalat='" + place.Coordinate.Longitude + "' datalong='" + place.Coordinate.Latitude + "'>"
                                 + "<a href='javascript:void(0)' class='viewmap'>Xem</a>"
                                + "<a href='javascript:void(0)' class='setstartpoint'>Điểm đi</a>"
                                + "<a href='javascript:void(0)' class='setendpoint'>Điểm đến</a>"
                                + "<a href='javascript:void(0)' class='findplacearound'>Xung quanh</a>"
                            + "</span>"
                        + "</li>";
                    }
                }
            }

            return str;
        }
    }
}
